#include "spdlog/spdlog.h"

#include "../../inc/arcsoft_face_sdk.h"
#include "../../inc/amcomdef.h"
#include "../../inc/asvloffscreen.h"
#include "../../inc/merror.h"

#include "../base/utils.h"

#include "ai_engine_pool.h"

#define APPID "6v2wZSPMmzbEYQNHqooHFS7iuByHgyAxPoSK7KS9Maz9"
#define SDKKEY "CSL6ULxtXfn6Nu3kaFDwf4F93t4Djfg8NciWXHZAkhTv"

#define NSCALE 16
#define FACENUM 5

#define SafeFree(p) { if ((p)) free(p); (p) = NULL; }
#define SafeArrayDelete(p) { if ((p)) delete [] (p); (p) = NULL; }
#define SafeDelete(p) { if ((p)) delete (p); (p) = NULL; }


namespace ai::facial_recognition {


    AIEnginePool::AIEnginePool(unsigned int max_size) {
        // 初始化引擎
        for (unsigned int i = 0; i < max_size; ++i) {
            auto engine = init_facial_recognition_engine();
            if (engine != NULL) {
                engineHandles.push_back(engine);
            }
        }
    }

    AIEnginePool::~AIEnginePool() {
        for (auto handle : engineHandles) {
            //反初始化
            auto res = ASFUninitEngine(handle);
            if (res != MOK)
                spdlog::error("ASFUninitEngine fail: {0:d}.", res);
            else
                spdlog::info("ASFUninitEngine success: {0:d}.", res);
        }
    }


    MHandle AIEnginePool::init_facial_recognition_engine() {
        MHandle handle = NULL;
        spdlog::info("\n************* ArcFace SDK Info *****************\n");
        MRESULT res = MOK;
        ASF_ActiveFileInfo activeFileInfo = {0};
        res = ASFGetActiveFileInfo(&activeFileInfo);
        if (res != MOK) {
            spdlog::error("ASFGetActiveFileInfo fail: {0:d}.", res);
        } else {
            //这里仅获取了有效期时间，还需要其他信息直接打印即可
            char startDateTime[32];
            timestampToTime(activeFileInfo.startTime, startDateTime, 32);
            spdlog::info("startTime: {0:s}.", startDateTime);
            char endDateTime[32];
            timestampToTime(activeFileInfo.endTime, endDateTime, 32);
            spdlog::info("endTime: {0:s}.", endDateTime);
        }
        //        free(activeFileInfo);

        //SDK版本信息
        const ASF_VERSION version = ASFGetVersion();

        // std::cout << "version 的类型是：" << typeid(version).name() << std::endl;

        printf("\nVersion:%s\n", version.Version);
        printf("BuildDate:%s\n", version.BuildDate);
        printf("CopyRight:%s\n", version.CopyRight);

        spdlog::info("\n************* Face Recognition *****************\n");

        res = ASFOnlineActivation(APPID, SDKKEY);
        if (MOK != res && MERR_ASF_ALREADY_ACTIVATED != res)
            spdlog::info("ASFOnlineActivation fail: {0:d}", res);
        else
            // 90114 SDK已激活
            spdlog::info("ASFOnlineActivation success: {0:d}", res);

        //初始化引擎
        MInt32 mask = ASF_FACE_DETECT | ASF_FACERECOGNITION | ASF_AGE | ASF_GENDER | ASF_FACE3DANGLE | ASF_LIVENESS |
                      ASF_IR_LIVENESS;
        res = ASFInitEngine(ASF_DETECT_MODE_IMAGE, ASF_OP_0_ONLY, NSCALE, FACENUM, mask, &handle);
        if (res != MOK)
            spdlog::info("ASFInitEngine fail: {0:d}", res);
        else
            spdlog::info("ASFInitEngine success: {0:d}", res);

        return handle;
    }


    MHandle AIEnginePool::getEngineHandle() {
        std::lock_guard<std::mutex> lock(mutex);
        if (engineHandles.empty()) {
            engineHandles.push_back(init_facial_recognition_engine());
        }
        auto handle = engineHandles.back();
        engineHandles.pop_back();
        return handle;
    }

    void AIEnginePool::releaseEngineHandle(MHandle handle) {
        std::lock_guard<std::mutex> lock(mutex);
        engineHandles.push_back(handle);
    }

}